package com.zgw.fireline.design.edit;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TableEditor;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.wb.internal.core.model.JavaInfoUtils;
import org.eclipse.wb.internal.core.model.creation.ConstructorCreationSupport;
import org.eclipse.wb.internal.core.model.generation.GenerationUtils;
import org.eclipse.wb.internal.core.model.generation.statement.StatementGenerator;
import org.eclipse.wb.internal.core.model.property.ComplexProperty;
import org.eclipse.wb.internal.core.model.property.Property;
import org.eclipse.wb.internal.core.model.variable.LocalUniqueVariableSupport;
import org.eclipse.wb.internal.core.model.variable.VariableSupport;
import org.eclipse.wb.internal.core.utils.reflect.ReflectionUtils;
import org.eclipse.wb.internal.core.utils.ui.GridDataFactory;
import org.eclipse.wb.internal.core.utils.ui.GridLayoutFactory;
import org.eclipse.wb.internal.swt.model.widgets.TableColumnInfo;
import org.eclipse.wb.swt.SWTResourceManager;

import com.zgw.fireline.design.Model.DataTableInfo;
import com.zgw.fireline.design.Model.DatasetInfo;
import com.zgw.fireline.design.common.ExecutionUtils2;

public class DataTableColumnsDialog extends TitleAreaDialog {
	private Table tableSource;
	private Table tableTarget;
	private final DataTableInfo tableInfo;
	private SelectionAdapter editListener;

	/**
	 * Create the dialog.
	 * 
	 * @param parentShell
	 */
	public DataTableColumnsDialog(Shell parentShell, DataTableInfo tableInfo) {
		super(parentShell);
		setShellStyle(SWT.MAX | SWT.RESIZE);
		setHelpAvailable(false);
		this.tableInfo = tableInfo;
	}

	/**
	 * Create contents of the dialog.
	 * 
	 * @param parent
	 */
	@Override
	protected Control createDialogArea(Composite parent) {
		setTitle("设置表格列");
		Composite area = (Composite) super.createDialogArea(parent);
		Composite container = new Composite(area, SWT.NONE);
		GridLayout gl_container = new GridLayout(3, false);
		gl_container.verticalSpacing = 2;
		gl_container.marginTop = 5;
		container.setLayout(gl_container);
		container.setLayoutData(new GridData(GridData.FILL_BOTH));

		Label lblNewLabel = new Label(container, SWT.SHADOW_IN);
		lblNewLabel.setFont(SWTResourceManager.getFont("宋体", 11, SWT.NORMAL));
		lblNewLabel.setText("数据列：");
		new Label(container, SWT.NONE);

		Label lblNewLabel_1 = new Label(container, SWT.NONE);
		lblNewLabel_1.setFont(SWTResourceManager.getFont("宋体", 11, SWT.NORMAL));
		lblNewLabel_1.setText("表格列：");

		tableSource = new Table(container, SWT.BORDER | SWT.FULL_SELECTION);
		GridData gd_table = new GridData(SWT.FILL, SWT.FILL, false, true, 1, 1);
		gd_table.widthHint = 150;
		tableSource.setLayoutData(gd_table);
		tableSource.setHeaderVisible(true);
		tableSource.setLinesVisible(false);

		TableColumn tblclmnNewColumn = new TableColumn(tableSource, SWT.NONE);
		tblclmnNewColumn.setWidth(150);
		tblclmnNewColumn.setText("属性");

		Composite composite = new Composite(container, SWT.NONE);
		GridLayoutFactory.create(composite).noMargins();
		GridData gd_composite = new GridData(SWT.FILL, SWT.FILL, false, true,
				1, 1);
		gd_composite.widthHint = 75;
		composite.setLayoutData(gd_composite);

		Button btnNewButton = new Button(composite, SWT.NONE);
		btnNewButton.setBounds(30, 54, 39, 22);
		btnNewButton.setText("添加");
		btnNewButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				doAdd();
			}
		});
		GridDataFactory.create(btnNewButton).fillH().grabH();
		Button btnNewButton_1 = new Button(composite, SWT.NONE);
		btnNewButton_1.setText("添加全部");
		btnNewButton_1.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				doAddAll();
			}
		});
		new Label(composite, SWT.HORIZONTAL);

		GridDataFactory.create(btnNewButton_1).fillH().grabH();
		Button btnNewButton_2 = new Button(composite, SWT.NONE);
		btnNewButton_2.setText("移除");
		btnNewButton_2.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				doRemove();
			}
		});

		GridDataFactory.create(btnNewButton_2).fillH().grabH();
		Button btnNewButton_3 = new Button(composite, SWT.NONE);
		GridDataFactory.create(btnNewButton_3).fillH().grabH();
		btnNewButton_3.setLocation(25, 141);
		btnNewButton_3.setText("移除全部");
		btnNewButton_3.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				doRemoveAll();
			}
		});

		tableTarget = new Table(container, SWT.BORDER | SWT.FULL_SELECTION);
		tableTarget.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true,
				1, 1));
		tableTarget.setHeaderVisible(true);
		tableTarget.setLinesVisible(true);
		tableTarget.addListener(SWT.MeasureItem, new Listener() {
			public void handleEvent(Event event) {
				event.height = 25;
			}
		});
		tableTarget.addListener(SWT.EraseItem, new Listener() {
			public void handleEvent(Event event) {
				Rectangle bounds = event.getBounds();
				if (event.index == 1 && (event.detail & SWT.SELECTED) != 0) {
					Color oldForeground = event.gc.getForeground();
					Color oldBackground = event.gc.getBackground();
					event.gc.setBackground(event.item.getDisplay()
							.getSystemColor(SWT.COLOR_LIST_SELECTION));
					event.gc.setForeground(event.item.getDisplay()
							.getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT));
					event.gc.fillRectangle(bounds);
					/* restore the old GC colors */
					String text = ((TableItem) event.item).getText(event.index);
					Point p = event.gc.stringExtent(text);
					event.gc.drawText(text, event.x + 4, event.y
							+ (event.height - p.y) / 2);
					event.gc.setForeground(oldForeground);
					event.gc.setBackground(oldBackground);
					/* ensure that default selection is not drawn */
					event.detail &= ~SWT.SELECTED;
					event.detail &= ~SWT.FOREGROUND;
				}
			}
		});

		final TableEditor editor = new TableEditor(tableTarget);
		editor.grabHorizontal = true;
		editor.grabVertical = true;
		final Composite editorComp = new Composite(tableTarget, SWT.NONE);
		GridLayoutFactory.create(editorComp).noMargins();
		final Text text = new Text(editorComp, SWT.NONE);
		GridDataFactory.create(text).grab().fillH();
		text.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				if (editor.getItem() != null) {
					editor.getItem().setText(0, text.getText());
				}
			}
		});
		editorComp.setBackground(text.getBackground());

		editListener = new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				TableItem item = tableTarget.getSelection()[0];
				editor.setEditor(text.getParent(), item, 0);
				text.setText(item.getText(0));
				text.selectAll();
				text.setFocus();
			}
		};
		tableTarget.addSelectionListener(editListener);
		TableColumn tblclmnNewColumn_1 = new TableColumn(tableTarget, SWT.NONE);
		tblclmnNewColumn_1.setWidth(127);
		tblclmnNewColumn_1.setText("列名称");

		TableColumn tableColumn = new TableColumn(tableTarget, SWT.NONE);
		tableColumn.setWidth(149);
		tableColumn.setText("属性");
		initializeListener();
		initializeData();

		return area;
	}

	/**
	 * Create contents of the button bar.
	 * 
	 * @param parent
	 */
	@Override
	protected void createButtonsForButtonBar(Composite parent) {
		Button button = createButton(parent, IDialogConstants.OK_ID,
				IDialogConstants.OK_LABEL, true);
		button.setText("确定");
		Button button_1 = createButton(parent, IDialogConstants.CANCEL_ID,
				IDialogConstants.CANCEL_LABEL, false);
		button_1.setText("取消");
	}

	private void initializeListener() {

	}

	/**
	 * Return the initial size of the dialog.
	 */
	@Override
	protected Point getInitialSize() {
		return new Point(587, 438);
	}

	private void initializeData() {
		List<String> columnsList = new ArrayList<String>();
		try {
			for (TableColumnInfo c : tableInfo.getColumns()) {
				Property name = getColumnNameProperty(c);
				Property text = c.getPropertyByTitle("text");
				if (name != null) {
					TableItem item = new TableItem(tableTarget, SWT.NONE);
					item.setText(0, toString(text.getValue()));
					item.setText(1, toString(name.getValue()));
					item.setData(toString(name.getValue()));
					columnsList.add(toString(name.getValue()));
				}
			}
		} catch (Throwable e) {
			throw ReflectionUtils.propagate(e);
		}
		final DatasetInfo dataset = tableInfo.getDataset();
		if (dataset != null) {
			// if (!dataset.isInstantiationData()) {
			// ExecutionUtils2.runErrorDlg("数据更新出现异常", new RunnableEx() {
			// public void run() throws Exception {
			// dataset.updateData();
			// }
			// });
			// }
			try {
				String[] columns = dataset.getDataColumns();
				columns = columns == null ? new String[] {} : columns;
				for (String c : columns) {
					if (columnsList.contains(c)) {
						continue;
					}
					TableItem item = new TableItem(tableSource, SWT.NONE);
					item.setText(c);
					item.setData(c); // 设置列属性
				}
			} catch (Exception e) {
				ExecutionUtils2.openErrorDialog("未能获得数据集列", e);
			}

		} else {
			MessageDialog.openWarning(getShell(), "警告", "未指定表格数据集");
		}

	}

	private String toString(Object obj) {
		if (obj instanceof String) {
			return (String) obj;
		}
		return "";
	}

	protected void doAdd() {
		if (tableSource.getSelectionCount() <= 0)
			return;
		TableItem item = tableSource.getSelection()[0];
		int index = tableSource.getSelectionIndex();
		TableItem item2 = new TableItem(tableTarget, SWT.NONE);
		item2.setText(1, item.getText(0));
		item2.setText(0, item.getText(0));
		item2.setData(item.getData());
		item.dispose();
		item2.setBackground(SWTResourceManager.getColor(243, 243, 243));
		if (tableSource.getItemCount() > index) {
			tableSource.select(index);
		} else if (tableSource.getItemCount() > 0) {
			tableSource.select(--index);
		}
		tableTarget.setSelection(item2);
		tableTarget.setFocus();
		editListener.widgetSelected(null);

	}

	protected void doAddAll() {
		// TODO Auto-generated method stub

	}

	protected void doRemove() {
		if (tableTarget.getSelectionCount() <= 0)
			return;
		TableItem item = tableTarget.getSelection()[0];
		int index = tableTarget.getSelectionIndex();
		TableItem item2 = new TableItem(tableSource, SWT.NONE);
		item2.setText(0, item.getText(1));
		item2.setData(item.getData());
		item.dispose();
		if (tableTarget.getItemCount() > index) {
			tableTarget.select(index);
		} else if (tableTarget.getItemCount() > 0) {
			tableTarget.select(--index);
		}
		tableSource.setSelection(item2);
		tableSource.setFocus();
		editListener.widgetSelected(null);
	}

	protected void doRemoveAll() {
		// TODO Auto-generated method stub

	}

	@Override
	protected void okPressed() {
		try {
			if (tableInfo.getColumns().size() == tableTarget.getItemCount()) {
				editColumns(null);// 不打开进度条
			} else {
				ProgressMonitorDialog progress = new ProgressMonitorDialog(
						getShell());
				progress.run(false, false, new IRunnableWithProgress() {
					public void run(IProgressMonitor monitor)
							throws InvocationTargetException,
							InterruptedException {
						try {
							editColumns(monitor);
						} finally {
							monitor.done();
						}
					}
				});
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		super.okPressed();
	}

	protected void editColumns(IProgressMonitor monitor) {
		Long l = new Date().getTime();
		try {
			Map<String, TableColumnInfo> oldColumns = new HashMap<String, TableColumnInfo>();
			for (TableColumnInfo c : tableInfo.getColumns()) {
				Property columnName = getColumnNameProperty(c);
				if (columnName != null) {
					oldColumns.put(toString(columnName.getValue()), c);
				}
			}
			if (monitor != null)
				monitor.beginTask("添加表格列", tableTarget.getItemCount());
			for (TableItem i : tableTarget.getItems()) {
				String name = (String) i.getData();
				if (name == null || name.trim().equals(""))
					continue;

				TableColumnInfo info = oldColumns.get(name);
				if (info == null) {
					info = (TableColumnInfo) JavaInfoUtils.createJavaInfo(
							tableInfo.getEditor(),
							"com.zgw.fireline.base.controls.DataTableColumn",
							new ConstructorCreationSupport(null, false));
					VariableSupport variableSupport = new LocalUniqueVariableSupport(
							info);
					StatementGenerator statementGenerator = GenerationUtils
							.getStatementGenerator(info);
					JavaInfoUtils.add(info, variableSupport,
							statementGenerator, null, tableInfo, null);
					info.getPropertyByTitle("width").setValue(80);
					getColumnNameProperty(info).setValue(name);
				}
				if (!i.getText(0).equals(
						info.getPropertyByTitle("text").getValue())) {
					info.getPropertyByTitle("text").setValue(i.getText(0));
				}
				if (monitor != null) {
					monitor.subTask(i.getText(0));
					monitor.worked(1);
				}
				oldColumns.remove(name);
			}
			for (TableColumnInfo c : oldColumns.values()) {
				JavaInfoUtils.deleteJavaInfo(c, true);
			}
		} catch (Exception e) {
			throw ReflectionUtils.propagate(e);
		}
		System.out.println(new Date().getTime() - l);
	}

	private Property getColumnNameProperty(TableColumnInfo i) throws Exception {
		Assert.isTrue(i.getDescription().getComponentClass().getName()
				.equals("com.zgw.fireline.base.controls.DataTableColumn"));

		ComplexProperty constructor = (ComplexProperty) i
				.getPropertyByTitle("Constructor");
		return constructor.getProperties()[2];
	}
}
